#include <iostream>
#include <string>
#include <memory>
#include <array>

using namespace std;


/*
\ brief:  计算机部分游客
\ author: 清晨与猫鱼
*/
class ComputerPartVisitor {
public:

/*
\ brief:  内部类 电脑一部分
\ author: 清晨与猫鱼
*/
    class ComputerPart {
    public:
        virtual void accept(ComputerPartVisitor* computerPartVisitor) = 0;
    };

/*
\ brief:  键盘
\ author: 清晨与猫鱼
*/
    class Keyboard  
        : public ComputerPart {
    public:
        void accept(ComputerPartVisitor* computerPartVisitor) {
            computerPartVisitor->visit(this);
        }

    };

/*
\ brief:  监视器
\ author: 清晨与猫鱼
*/
    class Monitor    
        : public ComputerPart {
    public:
        void accept(ComputerPartVisitor* computerPartVisitor) {
            computerPartVisitor->visit(this);
        }

    };

/*
\ brief:  鼠标
\ author: 清晨与猫鱼
*/
    class Mouse      
        : public ComputerPart {
    public:
        void accept(ComputerPartVisitor* computerPartVisitor) {
            computerPartVisitor->visit(this);
        }

    };

/*
\ brief:  计算机
\ author: 清晨与猫鱼
*/
    class Computer       
        : public ComputerPart {
    public:
        explicit Computer() {
           parts_[0].reset(new Mouse);
           parts_[1].reset(new Keyboard);
           parts_[2].reset(new Monitor);
        }

        void accept(ComputerPartVisitor* computerPartVisitor) {
            for (int i = 0; i < parts_.size(); ++i) {
                parts_[i]->accept(computerPartVisitor);
            }
            computerPartVisitor->visit(this);
        }

    private:
        array<unique_ptr<ComputerPart>, 3> parts_;

    };

// 访问接口
    virtual void visit(Computer* computer) = 0;
    virtual void visit(Mouse* computer) = 0;
    virtual void visit(Keyboard* computer) = 0;
    virtual void visit(Monitor* monitor)  = 0;
};


/*
\ brief:  显示部分访客
\ author: 清晨与猫鱼
*/
class ComputerPartDisplayVisitor 
    : public ComputerPartVisitor {
public:
    void visit(Computer* computer) {
        cout << "Displaying Computer." << endl;
    }

    void visit(Mouse* computer) {
        cout << "Displaying Mouse." << endl;
    }

    void visit(Keyboard* computer) {
        cout << "Displaying Keyboard." << endl;
    }

    void visit(Monitor* monitor) {
        cout << "Displaying Monitor." << endl;
    }

};